package iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.dal;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.database.DBHelper;
import iet.jxufe.cn.android.productanti_counterfeitingtraceabilitysystem.entity.Product;

public class ProductInfoDAL {
    private final DBHelper dbHelper;
    private static final String tableName = "ProductInfo";

    public ProductInfoDAL(Context context) {
        dbHelper = new DBHelper(context, false);
    }

    public long addOneProduct(Product newProduct) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("productId", newProduct.getProductId());
        values.put("productName", newProduct.getProductName());
        values.put("qrCode", newProduct.getQrCode());
        values.put("category", newProduct.getCategory());
        values.put("price", newProduct.getPrice());
        values.put("produceDate", newProduct.getProduceDate());
        values.put("state", newProduct.getState());

        try {
            return db.insertOrThrow(tableName, null, values);
        } catch (SQLiteConstraintException e) {
            return -1;
        } finally {
            db.close();
        }
    }

    public long addMassiveProducts(List<Product> newProducts) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        long rowsInserted = 0;

        db.beginTransaction();
        try {
            for (Product newProduct : newProducts) {
                ContentValues values = new ContentValues();
                values.put("productId", newProduct.getProductId());
                values.put("productName", newProduct.getProductName());
                values.put("qrCode", newProduct.getQrCode());
                values.put("category", newProduct.getCategory());
                values.put("price", newProduct.getPrice());
                values.put("produceDate", newProduct.getProduceDate());
                values.put("state", newProduct.getState());

                long result = db.insert(tableName, null, values);
                if (result != -1) {
                    rowsInserted++;
                }
            }
            db.setTransactionSuccessful();
        } catch (SQLiteConstraintException e) {
            e.printStackTrace();
        } finally {
            db.endTransaction();
            db.close();
        }

        return rowsInserted;
    }

    public long updateProductBaseInfo(Product newProduct) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("productName", newProduct.getProductName());
        values.put("category", newProduct.getCategory());
        values.put("price", newProduct.getPrice());

        try {
            return db.update(tableName, values, "productId = ?", new String[]{newProduct.getProductId()});
        } catch (SQLiteConstraintException e) {
            return -1;
        } finally {
            db.close();
        }
    }

    public long deleteProduct(String productId) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        try {
            return db.delete(tableName, "productId = ?", new String[]{productId});
        } catch (SQLiteConstraintException e) {
            return -1;
        } finally {
            db.close();
        }
    }

    public List<Product> searchProduct(String keyword) {
        List<Product> products = new ArrayList<>();
        SQLiteDatabase db = dbHelper.getReadableDatabase();

        String selection = "productName LIKE ? OR category LIKE ?";
        String[] selectionArgs = {
                "%" + keyword + "%",
                "%" + keyword + "%"
        };

        Cursor cursorProduct = db.query(
                tableName,
                null,
                selection,
                selectionArgs,
                null,
                null,
                null
        );

        try {
            if (cursorProduct != null) {
                while (cursorProduct.moveToNext()) {
                    String productId = cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("productId"));

                    Product product = new Product(
                            productId,
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("productName")),
                            cursorProduct.getBlob(cursorProduct.getColumnIndexOrThrow("qrCode")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("category")),
                            cursorProduct.getDouble(cursorProduct.getColumnIndexOrThrow("price")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("produceDate")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("manufactureDate")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("sellDate")),
                            cursorProduct.getInt(cursorProduct.getColumnIndexOrThrow("state"))
                    );

                    Log.d("TEST//", productId);

                    Cursor cursorTrace = db.query(
                            "TraceInfo",
                            new String[] { "producerImg" },
                            "productId = ?",
                            new String[] {productId},
                            null, null, null);

                    byte[] producerImg = null;
                    if (cursorTrace != null && cursorTrace.moveToFirst()) {
                        producerImg = cursorTrace.getBlob(cursorTrace.getColumnIndexOrThrow("producerImg"));
                        cursorTrace.close();
                    }
                    product.setImage(producerImg);

                    products.add(product);
                }

                cursorProduct.close();
            }

            return products;
        } finally {
            db.close();
        }
    }

    public List<Product> getAllProductsByState(Integer state, Integer mod) {
        List<Product> products = new ArrayList<>();
        SQLiteDatabase db = dbHelper.getReadableDatabase();

        String selection = null;
        String[] selectionArgs = null;

        if (state != -1) {
            selection = "state = ?";
            selectionArgs = new String[] { String.valueOf(state) };
        }

        Cursor cursorProduct = db.query(
                tableName,
                null,
                selection,
                selectionArgs,
                null,
                null,
                null);

        try {
            if (cursorProduct != null) {
                while (cursorProduct.moveToNext()) {
                    String productId = cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("productId"));
                    Product product = new Product(
                            productId,
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("productName")),
                            cursorProduct.getBlob(cursorProduct.getColumnIndexOrThrow("qrCode")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("category")),
                            cursorProduct.getDouble(cursorProduct.getColumnIndexOrThrow("price")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("produceDate")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("manufactureDate")),
                            cursorProduct.getString(cursorProduct.getColumnIndexOrThrow("sellDate")),
                            cursorProduct.getInt(cursorProduct.getColumnIndexOrThrow("state"))
                    );

                    String producerImgColumn;

                    switch(state)
                    {
                        case 3:
                            producerImgColumn = "dealerImg";
                            break;
                        case 4:
                            producerImgColumn = "dealerImg";
                            break;
                        case 5:
                            producerImgColumn = "consumerImg";
                            break;
                        default:
                            producerImgColumn = "producerImg";
                    }

                    Cursor cursorTrace = db.query(
                            "TraceInfo",
                            new String[] {producerImgColumn},
                            "productId = ?",
                            new String[] {productId},
                            null, null, null);

                    byte[] producerImg = null;
                    if (cursorTrace != null && cursorTrace.moveToFirst()) {
                        producerImg = cursorTrace.getBlob(cursorTrace.getColumnIndexOrThrow(producerImgColumn));
                        cursorTrace.close();
                    }
                    product.setImage(producerImg);

                    products.add(product);
                }

                cursorProduct.close();
            }

            return products;
        } finally {
            db.close();
        }
    }

    public Product getOneProductInfoById(String productId, Integer mod) {
        SQLiteDatabase db = dbHelper.getReadableDatabase();

        String selection = "productId = ?";
        String[] selectionArgs = new String[] { productId };

        Cursor cursor = db.query(
                tableName,
                null,
                selection,
                selectionArgs,
                null,
                null,
                null);

        try {
            if (cursor != null && cursor.moveToNext()) {
                Product product = new Product(
                        productId,
                        cursor.getString(cursor.getColumnIndexOrThrow("productName")),
                        cursor.getBlob(cursor.getColumnIndexOrThrow("qrCode")),
                        cursor.getString(cursor.getColumnIndexOrThrow("category")),
                        cursor.getDouble(cursor.getColumnIndexOrThrow("price")),
                        cursor.getString(cursor.getColumnIndexOrThrow("produceDate")),
                        cursor.getString(cursor.getColumnIndexOrThrow("manufactureDate")),
                        cursor.getString(cursor.getColumnIndexOrThrow("sellDate")),
                        cursor.getInt(cursor.getColumnIndexOrThrow("state"))
                );

                if (mod > 0) {
                    Cursor cursorTrace = db.query(
                            "TraceInfo",
                            new String[] { "producerImg" },
                            "productId = ?",
                            new String[] {productId},
                            null, null, null);

                    byte[] producerImg = null;
                    if (cursorTrace != null && cursorTrace.moveToFirst()) {
                        producerImg = cursorTrace.getBlob(cursorTrace.getColumnIndexOrThrow("producerImg"));
                        cursorTrace.close();
                    }

                    product.setImage(producerImg);
                }

                cursor.close();
                return product;
            }

            return null;
        } finally {
            db.close();
        }
    }

    public long updateOneProductState(String productId, Integer newState) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("state", String.valueOf(newState));

        if (newState == 2) {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = dateFormat.format(calendar.getTime());

            values.put("manufactureDate", formattedDate);
        } else if (newState == 4) {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = dateFormat.format(calendar.getTime());

            values.put("sellDate", formattedDate);
        }

        try {
            return db.update(tableName, values, "productId = ?", new String[]{ productId });
        } catch (SQLiteConstraintException e) {
            return -1;
        } finally {
            db.close();
        }
    }

    public long updateMassiveProductState(String[] productIds, Integer newState) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("state", String.valueOf(newState));

        if (newState == 2) {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = dateFormat.format(calendar.getTime());

            values.put("manufactureDate", formattedDate);
        } else if (newState == 4) {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String formattedDate = dateFormat.format(calendar.getTime());

            values.put("sellDate", formattedDate);
        }

        StringBuilder selection = new StringBuilder("productId IN (");
        for (int i = 0; i < productIds.length; i++) {
            selection.append("?");
            if (i < productIds.length - 1) {
                selection.append(", ");
            }
        }
        selection.append(")");

        try {
            return db.update(tableName, values, selection.toString(), productIds);
        } catch (SQLiteConstraintException e) {
            return -1;
        } finally {
            db.close();
        }
    }
}
